using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace lights
{
    public class comp_quickmesh : MonoBehaviour
    {
        // Start is called before the first frame update
        void Start()
        {

        }
        [HideInInspector]
        public Color[] _colors;

        public void InitColor()
        {
            this._colors = new Color[4];
            _colors[0] = new Color(0.8f, 0.1f, 0.1f);
            _colors[1] = new Color(0.3f, 0.8f, 0.1f);
            _colors[2] = new Color(0.1f, 0.1f, 0.7f);
            _colors[3] = new Color(0.8f, 0.7f, 0.1f);
        }
        [HideInInspector]
        public GameObject output_obj;
        public void UpdateChildColor(comp_quickmesh_elem c)
        {

            c.SetColor(_colors[c._colorindex]);

        }
        public void UpdateAllChildColor()
        {
            var comps = this.GetComponentsInChildren<comp_quickmesh_elem>();
            foreach (comp_quickmesh_elem c in comps)
            {
                UpdateChildColor(c);
            }
        }
        public void Bake()
        {
            MeshFilter filter = output_obj.GetComponent<MeshFilter>();
            if (filter == null)
                filter = output_obj.AddComponent<MeshFilter>();

            MeshRenderer render = output_obj.GetComponent<MeshRenderer>();
            if (render == null)
                render = output_obj.AddComponent<MeshRenderer>();

            comp_bakedmesh bmesh = output_obj.GetComponent<comp_bakedmesh>();
            if (bmesh == null)
            {
                bmesh = output_obj.AddComponent<comp_bakedmesh>();
            }

            var subitem = this.GetComponentsInChildren<comp_quickmesh_elem>();

            //mix mesh

            List<Vector3> pos = new List<Vector3>();
            List<int> indexs = new List<int>();
            List<Color> colors = new List<Color>();
            List<Matrix4x4> tpose = new List<Matrix4x4>();
            List<BoneWeight> weidghts = new List<BoneWeight>();





            var matroot = this.transform.worldToLocalMatrix;

            for (var i = 0; i < subitem.Length; i++)
            {
                int starti = pos.Count;
                var cindex = subitem[i]._colorindex;
                var color = new Color();
                if (cindex == 0)
                    color.r = 1;
                else if (cindex == 1)
                    color.g = 1;
                else if (cindex == 2)
                    color.b = 1;
                else if (cindex == 3)
                    color.a = 1;

                var srcmesh = subitem[i].GetComponent<MeshFilter>().sharedMesh;
                var matrix = matroot * subitem[i].transform.localToWorldMatrix;
                tpose.Add(matrix);
                foreach (var v in srcmesh.vertices)
                {
                    Vector4 v4 = v;
                    v4.w = 1;
                    var v2 = matrix * v4;
                    v2 /= v2.w;

                    pos.Add(v2);
                    colors.Add(color);
                    weidghts.Add(new BoneWeight()
                    { boneIndex0 = i, weight0 = 1.0f, weight1 = 0, weight2 = 0, weight3 = 0 });
                }
                foreach (var vi in srcmesh.triangles)
                {
                    indexs.Add(starti + vi);
                }
            }


            var time = DateTime.Now;
            var id = time.Year.ToString("d04") + time.Month.ToString("d02") + time.Day.ToString("d02")
               + "_" + time.Hour.ToString("d02") + time.Minute.ToString("d02") + time.Second.ToString("d02");


            if (!AssetDatabase.IsValidFolder("Assets/resources"))
                AssetDatabase.CreateFolder("Assets", "resources");
            if (!AssetDatabase.IsValidFolder("Assets/resources/quickmesh"))
                AssetDatabase.CreateFolder("Assets/resources", "quickmesh");



            var mesh = filter.sharedMesh;
            if (mesh == null)
            {
                mesh = new Mesh();
                mesh.name = "bake_" + id;
                var assetname = "Assets/resources/quickmesh/" + mesh.name + ".mesh";

                AssetDatabase.CreateAsset(mesh, assetname);
                filter.mesh = mesh = AssetDatabase.LoadAssetAtPath<Mesh>(assetname);
            }
            mesh.vertices = pos.ToArray();
            mesh.colors = colors.ToArray();
            mesh.bindposes = tpose.ToArray();
            mesh.boneWeights = weidghts.ToArray();
            mesh.triangles = indexs.ToArray();
            mesh.SetSubMesh(0, new UnityEngine.Rendering.SubMeshDescriptor()
            {
                topology = MeshTopology.Triangles,
                indexStart = 0,
                indexCount = indexs.Count,
            });
            mesh.RecalculateBounds();
            mesh.RecalculateNormals();
            mesh.RecalculateTangents();

            EditorUtility.SetDirty(mesh);
            AssetDatabase.SaveAssetIfDirty(mesh);
            AssetDatabase.SaveAssets();



            var mat = render.sharedMaterial;

            if (mat == null)
            {
                mat = new Material(Shader.Find("lights/polyshader"));
                mat.name = "bake_" + id;
                var matassetname = "Assets/resources/quickmesh/" + mat.name + ".mat";
                AssetDatabase.CreateAsset(mat, matassetname);
                render.material = mat = AssetDatabase.LoadAssetAtPath<Material>(matassetname);

            }


            mat.SetColor("_Color1", this._colors[0]);
            mat.SetColor("_Color2", this._colors[1]);
            mat.SetColor("_Color3", this._colors[2]);
            mat.SetColor("_Color4", this._colors[3]);
            EditorUtility.SetDirty(mat);
            AssetDatabase.SaveAssetIfDirty(mat);
            AssetDatabase.SaveAssets();
        }
        // Update is called once per frame
        void Update()
        {

        }
    }
}